grant-tables: do not fail attempts to GNTTABOP_set_version to the current version.
authorKeir Fraser <keir.fraser@citrix.com>
Thu, 3 Dec 2009 13:52:02 +0000 (13:52 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Thu, 3 Dec 2009 13:52:02 +0000 (13:52 +0000)
...even if there are active grants.

This triggers when checkpoint a guest which essentially resumes
without actually having gone through the suspend so the domain is
already latched to v2 inside Xen.

Also return the current actual version on success and failure. Not
terribly useful with only 2 options but is more robust to future
developments.

Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
xen/common/grant_table.c
xen/include/public/grant_table.h

index 1deac084732962cf51a4b24a4e0aabd520401f9e..d046ec11399a39bb318ccb14269964e68c361d89 100644 (file)
@@ -1972,14 +1972,19 @@ gnttab_set_version(XEN_GUEST_HANDLE(gnttab_set_version_t uop))
     struct domain *d = current->domain;
     struct grant_table *gt = d->grant_table;
     struct active_grant_entry *act;
-    long res = 0;
+    long res;
     int i;
 
     if (copy_from_guest(&op, uop, 1))
         return -EFAULT;
 
+    res = -EINVAL;
     if (op.version != 1 && op.version != 2)
-        return -EINVAL;
+        goto out;
+
+    res = 0;
+    if ( gt->gt_version == op.version )
+        goto out;
 
     spin_lock(&gt->lock);
     /* Make sure that the grant table isn't currently in use when we
@@ -1997,7 +2002,7 @@ gnttab_set_version(XEN_GUEST_HANDLE(gnttab_set_version_t uop))
                          gt->gt_version,
                          op.version);
                 res = -EBUSY;
-                goto out;
+                goto out_unlock;
             }
         }
     }
@@ -2009,7 +2014,7 @@ gnttab_set_version(XEN_GUEST_HANDLE(gnttab_set_version_t uop))
     {
         res = gnttab_populate_status_frames(d, gt);
         if ( res < 0)
-            goto out;
+            goto out_unlock;
     }
 
     if ( op.version < 2 && gt->gt_version == 2 )
@@ -2025,9 +2030,15 @@ gnttab_set_version(XEN_GUEST_HANDLE(gnttab_set_version_t uop))
 
     gt->gt_version = op.version;
 
-out:
+out_unlock:
     spin_unlock(&gt->lock);
 
+out:
+    op.version = gt->gt_version;
+
+    if (copy_to_guest(uop, &op, 1))
+        res = -EFAULT;
+
     return res;
 }
 
index abc0662608b7bb18f21079746203f45bc9bf7da9..84a7e7d25e05de9d7c4e88daafdc4b6a6185b42a 100644 (file)
@@ -463,7 +463,7 @@ DEFINE_XEN_GUEST_HANDLE(gnttab_unmap_and_replace_t);
  */
 #define GNTTABOP_set_version          8
 struct gnttab_set_version {
-    /* IN parameters */
+    /* IN/OUT parameters */
     uint32_t version;
 };
 typedef struct gnttab_set_version gnttab_set_version_t;